# ~*~ coding: utf-8 ~*~
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import InputRequired, ValidationError

from apps.common.form import ErrorFormMinx
from apps.common.validators import Number
from apps.assets.utils.genkey import validate_ssh_private_key, ssh_pubkey_gen
from ..models import SystemUser

__all__ = ['AdminUserCreateUpdateForm', 'SystemUserCreateUpdateForm']


class PasswordAndKeyAuthFormMinx(ErrorFormMinx):

    def validate_private_key(self, field):
        private_key = self.private_key.data
        if private_key:
            if not validate_ssh_private_key(private_key, None):
                raise ValidationError('无效的私钥')

    def gen_keys(self):
        username = self.username.data
        private_key = self.private_key.data
        public_key = None

        if private_key:
            public_key = ssh_pubkey_gen(private_key=private_key, username=username)
        return private_key, public_key


class AdminUserCreateUpdateForm(PasswordAndKeyAuthFormMinx, FlaskForm):
    name = StringField(validators=[InputRequired('用户名称不能为空')])
    username = StringField()
    password = StringField()
    private_key = StringField()

    def validate(self):
        if not super().validate():
            return False

        password = self.password.data
        private_key = self.private_key.data
        if not password and not private_key:
            self.update_error(
                {
                    'global': ['密码和私钥必须上传一个']
                }
            )
            return False

        return True

    class Meta:
        csrf = True

    @property
    def data(self):
        return {
            'name': self.name.data,
            'username': self.username.data,
            'password': self.password.data,
            'private_key': self.private_key.data,
        }


class SystemUserCreateUpdateForm(PasswordAndKeyAuthFormMinx, FlaskForm):
    name = StringField(validators=[InputRequired('用户名称不能为空')])
    username = StringField(validators=[InputRequired('系统用户不能为空')])
    login_mode = StringField(validators=[InputRequired('登录模式不能为空')])
    priority = StringField(validators=[Number('优先级必须填写数字')])
    auto_push = StringField()
    auto_generate_key = StringField()
    password = StringField()
    private_key = StringField()
    sudo = StringField(validators=[InputRequired('Sudo不能为空')])
    shell = StringField(validators=[InputRequired('Shell不能为空')])

    def validate(self):
        if not super().validate():
            return False

        # 不是自动生成秘钥，需要手动上传密码或者密钥
        if int(self.auto_generate_key.data) == 0 and self.login_mode.data == SystemUser.LOGIN_AUTO:
            password = self.password.data
            private_key = self.private_key.data
            if not password and not private_key:
                self.update_error(
                    {
                        'global': ['密码和私钥必须上传一个']
                    }
                )
                return False

        return True

    class Meta:
        csrf = True

    @property
    def data(self):
        return {
            'name': self.name.data,
            'username': self.username.data,
            'login_mode': self.login_mode.data,
            'priority': int(self.priority.data) if self.priority.data else None,
            'auto_push': int(self.auto_push.data),
            'auto_generate_key': int(self.auto_generate_key.data),
            'password': self.password.data,
            'private_key': self.private_key.data,
            'sudo': self.sudo.data,
            'shell': self.shell.data
        }
